package 并发包.并发辅助类;

import java.util.concurrent.CyclicBarrier;

/**
 * 【主题】CyclicBarrier
 * <p>
 * 字面意思回环栅栏，通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
 * 叫做回环是因为当所有等待线程都被释放以后，CyclicBarrier可以被重用。
 * 我们暂且把这个状态就叫做barrier，当调用await()方法之后，线程就处于barrier了。
 * </p>
 * Created by huangyu on 2018/9/1 14:12
 */
class Writer extends Thread {
	private CyclicBarrier cyclicBarrier;

	public Writer(CyclicBarrier cyclicBarrier) {
		this.cyclicBarrier = cyclicBarrier;
	}

	@Override
	public void run() {
		System.out.println("线程" + Thread.currentThread().getName() + ",正在写入数据");
		try {
			Thread.sleep(3000);// 以睡眠来模拟写入数据操作
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("线程" + Thread.currentThread().getName() + ",写入数据成功.....");

		try {
			cyclicBarrier.await();
		} catch (Exception e) {
		}
		System.out.println("所有线程执行完毕..........");
	}
}

public class CyclicBarrierDemo {


	/**
	 * 【常用方法】
	 * 1.CyclicBarrier类位于java.util.concurrent包下，CyclicBarrier提供2个构造器:
	 * (参数parties指让几个线程或者任务等待至barrier状态; 参数barrierAction为当这些线程都达到barrier状态时会执行的内容。)
	 * public CyclicBarrier(int parties, Runnable barrierAction) {}
	 * public CyclicBarrier(int parties) {}
	 *
	 *
	 * 2.然后CyclicBarrier中最重要的方法就是await方法，它有2个重载版本:
	 * (第一个版本比较常用，用来挂起当前线程，直至所有线程都到达barrier状态再同时执行后续任务;
	 * 第二个版本是让这些线程等待至一定的时间，如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。)
	 * public int await() throws InterruptedException, BrokenBarrierException {};
	 * public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException {};
	 */

	/**
	 * 【应用场景】
	 * CyclicBarrier一般用于一组线程互相等待至某个状态，然后这一组线程再同时执行
	 */
	public static void main(String[] args) {
		CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
			@Override
			public void run() {
				System.out.println("线程都达到barrier状态时会执行的内容");
			}
		});
		for (int i = 0; i < 3; i++) {
			Writer writer = new Writer(cyclicBarrier);
			writer.start();
		}
	}

}



